Rustで書いたAWS Lambda関数を簡単にデプロイ&実行する
Introduction
以前、こんな記事を書いたのですが、
Rustでlambdaやる場合、クロスコンパイルしてzipつくってアップロードしたりとけっこう手間でした。
(↑ではcdk使ってるのでさらに面倒)
いまそのあたりがどうなっているのか調べたところ、
Cargo-Lambdaが最も楽とのことだったので、使ってみました。
Cargp LambdaはCargoのサブコマンドとして提供され、
Rust on AWS Lambdaをやるのに便利なコマンドを使うことができるとのことです。
Environment
- OS : MacOS 10.15.7
- rust : 1.61.0
※AWS Lambdaが使えるAWSアカウントとロールは設定済みと仮定
Setup
内部でzigつかってるのでzigをインストール。
% brew install zig
cargo-lambdaはHomebrewでインストール可能です。
% brew tap cargo-lambda/cargo-lambda % brew install cargo-lambda
Lambda用のaarch64-unknown-linux-gnuツールチェインをrustupでインストールしておきます。
% rustup target add aarch64-unknown-linux-gnu
Try
Cargo Lambdaはプロジェクトの作成から実行・デプロイまでのサブコマンドを提供してくれます。
まずはnewでRust Lambdaプロジェクトを作成。
Lambdaパッケージの作成
% cargo lambda new my-function-1 ? Is this function an HTTP function? (y/N) [type `yes` if the Lambda function is triggered by an API Gateway, Amazon Load Balancer(ALB), or a Lambda URL] ### "cargo lambda new --http FUNCTION_NAME "でも同じように作成可能です。 ### funtion urlはパブリックなので注意
my-function-1は私がつけたlambdaのパッケージ名です。
newコマンドによってAWS Lambda on Rustの雛形を作成します。
また、プロジェクト作成時に↑で聞かれているように、
function urlを有効化した状態でLambda関数を作成することもできます。
(今回はyesを入力)
HTTP functionを使用しない場合(質問にNoとした場合)、
Lambdaが受け取るイベントタイプを選択できます。
ちなみに、newコマンド実行時に--templateオプションを使えば、独自のテンプレート構造を使用できます。
ビルド
プロジェクト作成後、すぐにbuildできます。
% cd my-function-1 % cargo lambda build --output-format zip warning: `my-function-1` (bin "my-function-1") generated 2 warnings Finished dev [unoptimized + debuginfo] target(s) in 0.47s % ls target/lambda/my-function-1/ bootstrap bootstrap.zip
--output-format zipをつけると、ビルド後に
zip(Lambdaパッケージとしてアップロード可能な形式)も作ってくれます。
リリースモードでビルドしたい場合は--releaseでOKです。
% cargo lambda build --output-format zip --release
Watchコマンドでローカル実行
watchコマンドは、以前startと呼ばれていたコマンドとのことです。
このコマンドを使うことで、ローカルでLambdaのエミュレータサーバを起動することができます。
% cargo lambda watch INFO cargo_lambda_watch: invoke server listening on 127.0.0.1:9000
エミュレーターサーバではfunction urlがサポートされているので、
http://127.0.0.1:9000/lambda-url/<関数名>
でアクセスすることができます。
今回であれば下記のようにcurlを実行します。
% curl -L http://127.0.0.1:9000/lambda-url/my-function-1 Hello AWS Lambda HTTP request
invokeで関数の実行
エミュレータサーバを実行した状態で、cargo lambda invokeコマンドを使って
Lambdaを実行することもできます。
ここにある内容をapigw-request.jsonという名前で保存し、
data-exampleオプションをつかって実行します。
% cargo lambda invoke my-function-1 --data-example apigw-request {"statusCode":200,"headers":{"content-type":"text/html"}, "multiValueHeaders":{"content-type":["text/html"]},"body":"Hello AWS Lambda HTTP request","isBase64Encoded":false}
※なぜjsonを指定しないと動かないか不明
ちなみに、function urlを使わないLambdaのinvokeであれば、
jsonファイルを用意しなくてもinvokeできました。
デプロイ
ローカルで動作確認できたらデプロイします。
cargo lambda deployコマンドを使って、
iam roleのarnを指定すればデプロイ可能です。
% cargo lambda deploy --enable-function-url my-function-1 --iam-role <iamロールのArn> ? function arn: arn:aws:lambda:XXXXXXXXXXXXXXXXXXX function url: https://somethingurl.lambda-url.us-east-1.on.aws/
デプロイ完了時、function urlが生成されてます。
生成されたURLにブラウザでアクセスすることが可能です。
※publicなので注意
invokeコマンドで--remoteオプションを使えば、本番環境のLambdaを実行できます。
% cargo lambda invoke --remote my-function-1 --data-example apigw-request {"statusCode":200,"headers":{"content-type":"text/html"}, "multiValueHeaders":{"content-type":["text/html"]},"body":"Hello AWS Lambda HTTP request","isBase64Encoded":false}
Summary
今回はCargo Lambdaを使ってみました。
以前よりAWS Lambda on Rustを使うのがだいぶ簡単になってますね。
AWS Lambda on Rust with CDKの場合でも
こんなのがあるので、
こちらも試してみたいところです。